import moment from 'moment';
import chartOption from '../configs/ChartConfig.json';

export default class DataUtil {
  static parseInstranceId(instanceId) {
    if (!instanceId) {
      return {
        instance: undefined,
        owner: undefined
      };
    }
    const index0 = instanceId.lastIndexOf('//');
    const index1 = instanceId.lastIndexOf('.');
    const index2 = instanceId.lastIndexOf(':');
    return {
      instance: instanceId.substring(index0 + 2, index1),
      owner: instanceId.substring(index1 + 1, index2)
    };
  }

  static parseName(name) {
    return name ? name.split('\n') : ['', ''];
  }

  static convertHistory2List(history) {
    return Object.keys(history).reduce((arr, k) => arr.concat(history[k]), []).sort((a, b) => {
      if (moment(a).isBefore(moment(b))) {
        return 1;
      }
      return -1;
    });
  }

  static convertData2Sections(data) {
    const ret = [];
    if (!data) {
      return ret;
    }
    const groupData = data.reduce((dict, item) => {
      if (dict[item.description]) {
        dict[item.description].push(item);
      } else {
        dict[item.description] = [item];
      }
      return dict;
    }, {});
    Object.keys(groupData).forEach((key) => {
      ret.push(
        {
          data: groupData[key],
          title: key
        }
      );
    });
    return ret;
  }

  static convertDataForChart(dataSource) {
    const ret = [];
    if (dataSource.length === 0) {
      return ret;
    }
    const lineOption = {
      type: 'LineChart',
      name: 'composite',
      series: []
    };
    dataSource.forEach(({ type, name, item }) => {
      if (type === 'GaugeChart') {
        const gaugeOption = {
          type,
          name,
          series: [DataUtil.getGuageSeries(name, item)]
        };
        ret.push(gaugeOption);
      } else if (type === 'LineChart') {
        const aSeries = DataUtil.getLineOptions(name, item);
        lineOption.series.push(aSeries);
      }
    });
    ret.sort((a, b) => a.name.localeCompare(b.name));
    ret.unshift(lineOption);
    return ret;
  }

  static getGuageSeries(name, item) {
    return {
      type: 'gauge',
      min: chartOption[name].min,
      max: chartOption[name].max,
      name: chartOption[name].name,
      detail: { formatter: '{value}', fontSize: 14 },
      data: [{ value: item[item.length - 1].value.toFixed(2) }]
    };
  }

  // a data: [{name: '', value: ["time", "val"] }]
  static getLineOptions(name, item) {
    item.sort((a, b) => (moment(a.timeStamp).isBefore(moment(b.timeStamp)) ? -1 : 1));
    const retValues = item.map(({ timeStamp, value }) => (
      {
        name: `${moment(timeStamp).toDate()}`,
        value: [`${moment(timeStamp).format('YYYY-MM-DD HH:mm:ss')}`, value.toFixed(2)]
      }
    ));
    return {
      name: chartOption[name].name,
      type: 'line',
      data: retValues
    };
  }

  static mergeList(preData, newData) {
    if (preData.length > 100) {
      preData.splice(0, 20);
    }
    const tmp = preData.concat(newData);
    const obj = tmp.reduce((acc, cur) => {
      acc[cur.timeStamp] = cur.value;
      return acc;
    }, {});
    return Object.keys(obj).map((key) => ({ timeStamp: key, value: obj[key] }));
  }

  static appendData(preData, newData) {
    for (let i = 0; i < preData.length; i += 1) {
      const tmpPre = preData[i];
      if (tmpPre.type !== 'GaugeChart') {
        for (let j = 0; j < newData.length; j += 1) {
          const tmpNew = newData[j];
          if (tmpNew.type !== 'GaugeChart') {
            if (tmpNew.name === tmpPre.name) {
              tmpNew.item = this.mergeList(tmpPre.item, tmpNew.item);
            }
          }
        }
      }
    }
  }
}
